<template>
  <div class="container" ref="container"></div>
</template>

<script setup>
import { ref, onMounted } from "vue";
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";

const container = ref();

// Our Javascript will go here.
// 创建场景
const scene = new THREE.Scene();
// 改变场景的背景-颜色
scene.background = new THREE.Color(0x666666);

// 创建相机
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);
// 调整相机位置
camera.position.z = 2;
camera.position.y = 2;
// 创建立方体
const gemoetry = new THREE.BoxGeometry(1, 1, 1);

// 创建材质(受光源影响的)
const material = new THREE.MeshPhongMaterial({
  color: 0x0099ff,
  shininess: 300,
});

// 创建 Mesh
const cube = new THREE.Mesh(gemoetry, material);
cube.position.set(0, 0.5, 0);

// 物体接受光源
cube.receiveShadow = true;

// 物体能够投射光源
cube.castShadow = true;

// 将物体添加到场景
scene.add(cube);

// 添加灯光
const light = new THREE.AmbientLight(0xffffff, 1);
scene.add(light);

// 添加点光源
const pointLight = new THREE.PointLight(0xffffff, 100, 100);
pointLight.position.set(5, 3, 5);
// 允许有阴影
pointLight.castShadow = true;
scene.add(pointLight);

// 创建地面
const meshFloor = new THREE.Mesh(
  new THREE.PlaneGeometry(10, 10),
  new THREE.MeshPhongMaterial({
    color: 0x1b5e20,
  })
);
meshFloor.rotation.x -= Math.PI / 2;
// 地面设置可以接受光源
meshFloor.receiveShadow = true;
scene.add(meshFloor);

// 创建渲染器
const renderer = new THREE.WebGLRenderer();
// 调整渲染器窗口大小
renderer.setSize(window.innerWidth, window.innerHeight);
// 允许渲染器可以渲染阴影效果
renderer.shadowMap.enabled = true;
// 添加一个网格地面
const gridHepler = new THREE.GridHelper(10, 10);
scene.add(gridHepler);

// 在页面中添加元素
onMounted(() => {
  // 将渲染节点添加到页面
  container.value.appendChild(renderer.domElement);
});

// 添加轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);

// 开启阻尼效果 （视角拖动的时候会有惯性）
controls.enableDamping = true; // 开启
controls.dampingFactor = 0.05; // 阻尼惯性大小

// 添加坐标轴
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);

// 让立方体动起来
function animate() {
  requestAnimationFrame(animate);

  // 轨道控制器更新
  controls.update();
  // 调用渲染器进行渲染
  renderer.render(scene, camera);
}

animate();
</script>

<style>
* {
  margin: 0;
}
html,
body {
  width: 100vw;
  height: 100vh;
}

.container {
  width: 100vw;
  height: 100vh;
  overflow: hidden;
}

.buttons {
  left: 20px;
  position: fixed;
  top: 20px;
}

#gui {
  position: absolute;
  right: 0;
  width: 300px;
}
</style>
